Skip to main content

core/stdarch/crates/core_arch/src/x86/
mod.rs

1//! `x86` and `x86_64` intrinsics.
2
3use crate::mem::transmute;
4
5#[macro_use]
6mod macros;
7
8/// The x87 80-bit extended-precision floating-point type.
9///
10/// FIXME: extend the documentation.
11#[doc(alias = "long double")]
12#[doc(alias = "x86_fp80")]
13#[doc(alias = "__float80")]
14#[unstable(feature = "x87_f80", issue = "163982")]
15#[allow(non_camel_case_types)]
16#[doc(cfg(any(target_arch = "x86", target_arch = "x86_64")))]
17#[derive(Clone, Copy)]
18#[repr(transparent)]
19pub struct x87_f80(crate::num::imp::x87_f80::x87_f80);
20
21const _: () = assert!(
22    size_of::<x87_f80>()
23        == cfg_select! {
24            target_arch = "x86" => cfg_select! {
25                target_vendor = "apple" => 16,
26                target_env = "msvc" => 16,
27                _ => 12,
28            },
29            target_arch = "x86_64" => 16,
30            _ => size_of::<x87_f80>(), // for doc builds
31        }
32);
33
34const _: () = assert!(
35    align_of::<x87_f80>()
36        == cfg_select! {
37            target_arch = "x86" => cfg_select! {
38                target_vendor = "apple" => 16,
39                target_env = "msvc" => 16,
40                _ => 4,
41            },
42            target_arch = "x86_64" => 16,
43            _ => align_of::<x87_f80>(), // for doc builds
44        }
45);
46
47#[unstable(feature = "x87_f80", issue = "163982")]
48impl crate::fmt::Debug for x87_f80 {
49    #[inline]
50    fn fmt(&self, f: &mut crate::fmt::Formatter<'_>) -> crate::fmt::Result {
51        let mut bytes = [0u8; 16];
52        bytes[..10].copy_from_slice(&self.to_ne_bytes());
53        write!(f, "x87_f80({:#022x})", u128::from_ne_bytes(bytes))
54    }
55}
56
57impl x87_f80 {
58    /// Returns the memory representation of this floating point number as a byte array in
59    /// native byte order.
60    #[unstable(feature = "x87_f80", issue = "163982")]
61    #[inline]
62    pub const fn to_ne_bytes(self) -> [u8; 10] {
63        // SAFETY: the first 10 bytes are initialized.
64        unsafe { (&raw const self).cast::<[u8; 10]>().read() }
65    }
66
67    /// Creates a floating point value from its representation as a byte array in native endian.
68    #[unstable(feature = "x87_f80", issue = "163982")]
69    #[inline]
70    pub const fn from_ne_bytes(bytes: [u8; 10]) -> Self {
71        // SAFETY: we initialize the first 10 bytes, the remaining bytes remain uninitialized.
72        // That is exactly the layout of x87_f80.
73        unsafe {
74            let mut this = crate::mem::MaybeUninit::<x87_f80>::uninit();
75            this.as_mut_ptr().cast::<[u8; 10]>().write(bytes);
76            this.assume_init()
77        }
78    }
79}
80
81types! {
82    #![stable(feature = "simd_x86", since = "1.27.0")]
83
84    /// 128-bit wide integer vector type, x86-specific
85    ///
86    /// This type is the same as the `__m128i` type defined by Intel,
87    /// representing a 128-bit SIMD register. Usage of this type typically
88    /// corresponds to the `sse` and up target features for x86/x86_64.
89    ///
90    /// Internally this type may be viewed as:
91    ///
92    /// * `i8x16` - sixteen `i8` variables packed together
93    /// * `i16x8` - eight `i16` variables packed together
94    /// * `i32x4` - four `i32` variables packed together
95    /// * `i64x2` - two `i64` variables packed together
96    ///
97    /// (as well as unsigned versions). Each intrinsic may interpret the
98    /// internal bits differently, check the documentation of the intrinsic
99    /// to see how it's being used.
100    ///
101    /// The in-memory representation of this type is the same as the one of an
102    /// equivalent array (i.e. the in-memory order of elements is the same, and
103    /// there is no padding); however, the alignment is different and equal to
104    /// the size of the type. Note that the ABI for function calls may *not* be
105    /// the same.
106    ///
107    /// Note that this means that an instance of `__m128i` typically just means
108    /// a "bag of bits" which is left up to interpretation at the point of use.
109    ///
110    /// Most intrinsics using `__m128i` are prefixed with `_mm_` and the
111    /// integer types tend to correspond to suffixes like "epi8" or "epi32".
112    ///
113    /// # Examples
114    ///
115    /// ```
116    /// # #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] {
117    /// #[cfg(target_arch = "x86")]
118    /// use std::arch::x86::*;
119    /// #[cfg(target_arch = "x86_64")]
120    /// use std::arch::x86_64::*;
121    ///
122    /// # #[target_feature(enable = "sse2")]
123    /// # #[allow(unused_unsafe)] // temporary, to unstick CI
124    /// # unsafe fn foo() { unsafe {
125    /// let all_bytes_zero = _mm_setzero_si128();
126    /// let all_bytes_one = _mm_set1_epi8(1);
127    /// let four_i32 = _mm_set_epi32(1, 2, 3, 4);
128    /// # }}
129    /// # if is_x86_feature_detected!("sse2") { unsafe { foo() } }
130    /// # }
131    /// ```
132    #[doc(cfg(any(target_arch = "x86", target_arch = "x86_64")))]
133    pub struct __m128i(2 x i64);
134
135    /// 128-bit wide set of four `f32` types, x86-specific
136    ///
137    /// This type is the same as the `__m128` type defined by Intel,
138    /// representing a 128-bit SIMD register which internally is consisted of
139    /// four packed `f32` instances. Usage of this type typically corresponds
140    /// to the `sse` and up target features for x86/x86_64.
141    ///
142    /// Note that unlike `__m128i`, the integer version of the 128-bit
143    /// registers, this `__m128` type has *one* interpretation. Each instance
144    /// of `__m128` always corresponds to `f32x4`, or four `f32` types packed
145    /// together.
146    ///
147    /// The in-memory representation of this type is the same as the one of an
148    /// equivalent array (i.e. the in-memory order of elements is the same, and
149    /// there is no padding); however, the alignment is different and equal to
150    /// the size of the type. Note that the ABI for function calls may *not* be
151    /// the same.
152    ///
153    /// Most intrinsics using `__m128` are prefixed with `_mm_` and are
154    /// suffixed with "ps" (or otherwise contain "ps"). Not to be confused with
155    /// "pd" which is used for `__m128d`.
156    ///
157    /// # Examples
158    ///
159    /// ```
160    /// # #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] {
161    /// #[cfg(target_arch = "x86")]
162    /// use std::arch::x86::*;
163    /// #[cfg(target_arch = "x86_64")]
164    /// use std::arch::x86_64::*;
165    ///
166    /// # #[target_feature(enable = "sse")]
167    /// # #[allow(unused_unsafe)] // temporary, to unstick CI
168    /// # unsafe fn foo() { unsafe {
169    /// let four_zeros = _mm_setzero_ps();
170    /// let four_ones = _mm_set1_ps(1.0);
171    /// let four_floats = _mm_set_ps(1.0, 2.0, 3.0, 4.0);
172    /// # }}
173    /// # if is_x86_feature_detected!("sse") { unsafe { foo() } }
174    /// # }
175    /// ```
176    #[doc(cfg(any(target_arch = "x86", target_arch = "x86_64")))]
177    pub struct __m128(4 x f32);
178
179    /// 128-bit wide set of two `f64` types, x86-specific
180    ///
181    /// This type is the same as the `__m128d` type defined by Intel,
182    /// representing a 128-bit SIMD register which internally is consisted of
183    /// two packed `f64` instances. Usage of this type typically corresponds
184    /// to the `sse` and up target features for x86/x86_64.
185    ///
186    /// Note that unlike `__m128i`, the integer version of the 128-bit
187    /// registers, this `__m128d` type has *one* interpretation. Each instance
188    /// of `__m128d` always corresponds to `f64x2`, or two `f64` types packed
189    /// together.
190    ///
191    /// The in-memory representation of this type is the same as the one of an
192    /// equivalent array (i.e. the in-memory order of elements is the same, and
193    /// there is no padding); however, the alignment is different and equal to
194    /// the size of the type. Note that the ABI for function calls may *not* be
195    /// the same.
196    ///
197    /// Most intrinsics using `__m128d` are prefixed with `_mm_` and are
198    /// suffixed with "pd" (or otherwise contain "pd"). Not to be confused with
199    /// "ps" which is used for `__m128`.
200    ///
201    /// # Examples
202    ///
203    /// ```
204    /// # #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] {
205    /// #[cfg(target_arch = "x86")]
206    /// use std::arch::x86::*;
207    /// #[cfg(target_arch = "x86_64")]
208    /// use std::arch::x86_64::*;
209    ///
210    /// # #[target_feature(enable = "sse2")]
211    /// # #[allow(unused_unsafe)] // temporary, to unstick CI
212    /// # unsafe fn foo() { unsafe {
213    /// let two_zeros = _mm_setzero_pd();
214    /// let two_ones = _mm_set1_pd(1.0);
215    /// let two_floats = _mm_set_pd(1.0, 2.0);
216    /// # }}
217    /// # if is_x86_feature_detected!("sse2") { unsafe { foo() } }
218    /// # }
219    /// ```
220    #[doc(cfg(any(target_arch = "x86", target_arch = "x86_64")))]
221    pub struct __m128d(2 x f64);
222
223    /// 256-bit wide integer vector type, x86-specific
224    ///
225    /// This type is the same as the `__m256i` type defined by Intel,
226    /// representing a 256-bit SIMD register. Usage of this type typically
227    /// corresponds to the `avx` and up target features for x86/x86_64.
228    ///
229    /// Internally this type may be viewed as:
230    ///
231    /// * `i8x32` - thirty two `i8` variables packed together
232    /// * `i16x16` - sixteen `i16` variables packed together
233    /// * `i32x8` - eight `i32` variables packed together
234    /// * `i64x4` - four `i64` variables packed together
235    ///
236    /// (as well as unsigned versions). Each intrinsic may interpret the
237    /// internal bits differently, check the documentation of the intrinsic
238    /// to see how it's being used.
239    ///
240    /// The in-memory representation of this type is the same as the one of an
241    /// equivalent array (i.e. the in-memory order of elements is the same, and
242    /// there is no padding); however, the alignment is different and equal to
243    /// the size of the type. Note that the ABI for function calls may *not* be
244    /// the same.
245    ///
246    /// Note that this means that an instance of `__m256i` typically just means
247    /// a "bag of bits" which is left up to interpretation at the point of use.
248    ///
249    /// # Examples
250    ///
251    /// ```
252    /// # #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] {
253    /// #[cfg(target_arch = "x86")]
254    /// use std::arch::x86::*;
255    /// #[cfg(target_arch = "x86_64")]
256    /// use std::arch::x86_64::*;
257    ///
258    /// # #[target_feature(enable = "avx")]
259    /// # #[allow(unused_unsafe)] // temporary, to unstick CI
260    /// # unsafe fn foo() { unsafe {
261    /// let all_bytes_zero = _mm256_setzero_si256();
262    /// let all_bytes_one = _mm256_set1_epi8(1);
263    /// let eight_i32 = _mm256_set_epi32(1, 2, 3, 4, 5, 6, 7, 8);
264    /// # }}
265    /// # if is_x86_feature_detected!("avx") { unsafe { foo() } }
266    /// # }
267    /// ```
268    #[doc(cfg(any(target_arch = "x86", target_arch = "x86_64")))]
269    pub struct __m256i(4 x i64);
270
271    /// 256-bit wide set of eight `f32` types, x86-specific
272    ///
273    /// This type is the same as the `__m256` type defined by Intel,
274    /// representing a 256-bit SIMD register which internally is consisted of
275    /// eight packed `f32` instances. Usage of this type typically corresponds
276    /// to the `avx` and up target features for x86/x86_64.
277    ///
278    /// Note that unlike `__m256i`, the integer version of the 256-bit
279    /// registers, this `__m256` type has *one* interpretation. Each instance
280    /// of `__m256` always corresponds to `f32x8`, or eight `f32` types packed
281    /// together.
282    ///
283    /// The in-memory representation of this type is the same as the one of an
284    /// equivalent array (i.e. the in-memory order of elements is the same, and
285    /// there is no padding  between two consecutive elements); however, the
286    /// alignment is different and equal to the size of the type. Note that the
287    /// ABI for function calls may *not* be the same.
288    ///
289    /// Most intrinsics using `__m256` are prefixed with `_mm256_` and are
290    /// suffixed with "ps" (or otherwise contain "ps"). Not to be confused with
291    /// "pd" which is used for `__m256d`.
292    ///
293    /// # Examples
294    ///
295    /// ```
296    /// # #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] {
297    /// #[cfg(target_arch = "x86")]
298    /// use std::arch::x86::*;
299    /// #[cfg(target_arch = "x86_64")]
300    /// use std::arch::x86_64::*;
301    ///
302    /// # #[target_feature(enable = "avx")]
303    /// # #[allow(unused_unsafe)] // temporary, to unstick CI
304    /// # unsafe fn foo() { unsafe {
305    /// let eight_zeros = _mm256_setzero_ps();
306    /// let eight_ones = _mm256_set1_ps(1.0);
307    /// let eight_floats = _mm256_set_ps(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0);
308    /// # }}
309    /// # if is_x86_feature_detected!("avx") { unsafe { foo() } }
310    /// # }
311    /// ```
312    #[doc(cfg(any(target_arch = "x86", target_arch = "x86_64")))]
313    pub struct __m256(8 x f32);
314
315    /// 256-bit wide set of four `f64` types, x86-specific
316    ///
317    /// This type is the same as the `__m256d` type defined by Intel,
318    /// representing a 256-bit SIMD register which internally is consisted of
319    /// four packed `f64` instances. Usage of this type typically corresponds
320    /// to the `avx` and up target features for x86/x86_64.
321    ///
322    /// Note that unlike `__m256i`, the integer version of the 256-bit
323    /// registers, this `__m256d` type has *one* interpretation. Each instance
324    /// of `__m256d` always corresponds to `f64x4`, or four `f64` types packed
325    /// together.
326    ///
327    /// The in-memory representation of this type is the same as the one of an
328    /// equivalent array (i.e. the in-memory order of elements is the same, and
329    /// there is no padding); however, the alignment is different and equal to
330    /// the size of the type. Note that the ABI for function calls may *not* be
331    /// the same.
332    ///
333    /// Most intrinsics using `__m256d` are prefixed with `_mm256_` and are
334    /// suffixed with "pd" (or otherwise contain "pd"). Not to be confused with
335    /// "ps" which is used for `__m256`.
336    ///
337    /// # Examples
338    ///
339    /// ```
340    /// # #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] {
341    /// #[cfg(target_arch = "x86")]
342    /// use std::arch::x86::*;
343    /// #[cfg(target_arch = "x86_64")]
344    /// use std::arch::x86_64::*;
345    ///
346    /// # #[target_feature(enable = "avx")]
347    /// # #[allow(unused_unsafe)] // temporary, to unstick CI
348    /// # unsafe fn foo() { unsafe {
349    /// let four_zeros = _mm256_setzero_pd();
350    /// let four_ones = _mm256_set1_pd(1.0);
351    /// let four_floats = _mm256_set_pd(1.0, 2.0, 3.0, 4.0);
352    /// # }}
353    /// # if is_x86_feature_detected!("avx") { unsafe { foo() } }
354    /// # }
355    /// ```
356    #[doc(cfg(any(target_arch = "x86", target_arch = "x86_64")))]
357    pub struct __m256d(4 x f64);
358}
359
360types! {
361    #![stable(feature = "simd_avx512_types", since = "1.72.0")]
362
363    /// 512-bit wide integer vector type, x86-specific
364    ///
365    /// This type is the same as the `__m512i` type defined by Intel,
366    /// representing a 512-bit SIMD register. Usage of this type typically
367    /// corresponds to the `avx512*` and up target features for x86/x86_64.
368    ///
369    /// Internally this type may be viewed as:
370    ///
371    /// * `i8x64` - sixty-four `i8` variables packed together
372    /// * `i16x32` - thirty-two `i16` variables packed together
373    /// * `i32x16` - sixteen `i32` variables packed together
374    /// * `i64x8` - eight `i64` variables packed together
375    ///
376    /// (as well as unsigned versions). Each intrinsic may interpret the
377    /// internal bits differently, check the documentation of the intrinsic
378    /// to see how it's being used.
379    ///
380    /// The in-memory representation of this type is the same as the one of an
381    /// equivalent array (i.e. the in-memory order of elements is the same, and
382    /// there is no padding); however, the alignment is different and equal to
383    /// the size of the type. Note that the ABI for function calls may *not* be
384    /// the same.
385    ///
386    /// Note that this means that an instance of `__m512i` typically just means
387    /// a "bag of bits" which is left up to interpretation at the point of use.
388    pub struct __m512i(8 x i64);
389
390    /// 512-bit wide set of sixteen `f32` types, x86-specific
391    ///
392    /// This type is the same as the `__m512` type defined by Intel,
393    /// representing a 512-bit SIMD register which internally is consisted of
394    /// eight packed `f32` instances. Usage of this type typically corresponds
395    /// to the `avx512*` and up target features for x86/x86_64.
396    ///
397    /// Note that unlike `__m512i`, the integer version of the 512-bit
398    /// registers, this `__m512` type has *one* interpretation. Each instance
399    /// of `__m512` always corresponds to `f32x16`, or sixteen `f32` types
400    /// packed together.
401    ///
402    /// The in-memory representation of this type is the same as the one of an
403    /// equivalent array (i.e. the in-memory order of elements is the same, and
404    /// there is no padding  between two consecutive elements); however, the
405    /// alignment is different and equal to the size of the type. Note that the
406    /// ABI for function calls may *not* be the same.
407    ///
408    /// Most intrinsics using `__m512` are prefixed with `_mm512_` and are
409    /// suffixed with "ps" (or otherwise contain "ps"). Not to be confused with
410    /// "pd" which is used for `__m512d`.
411    pub struct __m512(16 x f32);
412
413    /// 512-bit wide set of eight `f64` types, x86-specific
414    ///
415    /// This type is the same as the `__m512d` type defined by Intel,
416    /// representing a 512-bit SIMD register which internally is consisted of
417    /// eight packed `f64` instances. Usage of this type typically corresponds
418    /// to the `avx` and up target features for x86/x86_64.
419    ///
420    /// Note that unlike `__m512i`, the integer version of the 512-bit
421    /// registers, this `__m512d` type has *one* interpretation. Each instance
422    /// of `__m512d` always corresponds to `f64x8`, or eight `f64` types packed
423    /// together.
424    ///
425    /// The in-memory representation of this type is the same as the one of an
426    /// equivalent array (i.e. the in-memory order of elements is the same, and
427    /// there is no padding  between two consecutive elements); however, the
428    /// alignment is different and equal to the size of the type. Note that the
429    /// ABI for function calls may *not* be the same.
430    ///
431    /// Most intrinsics using `__m512d` are prefixed with `_mm512_` and are
432    /// suffixed with "pd" (or otherwise contain "pd"). Not to be confused with
433    /// "ps" which is used for `__m512`.
434    pub struct __m512d(8 x f64);
435}
436
437types! {
438    #![stable(feature = "stdarch_x86_avx512", since = "1.89")]
439
440    /// 128-bit wide set of eight `u16` types, x86-specific
441    ///
442    /// This type is representing a 128-bit SIMD register which internally is consisted of
443    /// eight packed `u16` instances. Its purpose is for bf16 related intrinsic
444    /// implementations.
445    ///
446    /// The in-memory representation of this type is the same as the one of an
447    /// equivalent array (i.e. the in-memory order of elements is the same, and
448    /// there is no padding); however, the alignment is different and equal to
449    /// the size of the type. Note that the ABI for function calls may *not* be
450    /// the same.
451    pub struct __m128bh(8 x u16);
452
453    /// 256-bit wide set of 16 `u16` types, x86-specific
454    ///
455    /// This type is the same as the `__m256bh` type defined by Intel,
456    /// representing a 256-bit SIMD register which internally is consisted of
457    /// 16 packed `u16` instances. Its purpose is for bf16 related intrinsic
458    /// implementations.
459    ///
460    /// The in-memory representation of this type is the same as the one of an
461    /// equivalent array (i.e. the in-memory order of elements is the same, and
462    /// there is no padding); however, the alignment is different and equal to
463    /// the size of the type. Note that the ABI for function calls may *not* be
464    /// the same.
465    pub struct __m256bh(16 x u16);
466
467    /// 512-bit wide set of 32 `u16` types, x86-specific
468    ///
469    /// This type is the same as the `__m512bh` type defined by Intel,
470    /// representing a 512-bit SIMD register which internally is consisted of
471    /// 32 packed `u16` instances. Its purpose is for bf16 related intrinsic
472    /// implementations.
473    ///
474    /// The in-memory representation of this type is the same as the one of an
475    /// equivalent array (i.e. the in-memory order of elements is the same, and
476    /// there is no padding); however, the alignment is different and equal to
477    /// the size of the type. Note that the ABI for function calls may *not* be
478    /// the same.
479    pub struct __m512bh(32 x u16);
480}
481
482types! {
483    #![stable(feature = "stdarch_x86_avx512fp16", since = "1.94.0")]
484
485    /// 128-bit wide set of 8 `f16` types, x86-specific
486    ///
487    /// This type is the same as the `__m128h` type defined by Intel,
488    /// representing a 128-bit SIMD register which internally is consisted of
489    /// 8 packed `f16` instances. its purpose is for f16 related intrinsic
490    /// implementations.
491    ///
492    /// The in-memory representation of this type is the same as the one of an
493    /// equivalent array (i.e. the in-memory order of elements is the same, and
494    /// there is no padding); however, the alignment is different and equal to
495    /// the size of the type. Note that the ABI for function calls may *not* be
496    /// the same.
497    pub struct __m128h(8 x f16);
498
499    /// 256-bit wide set of 16 `f16` types, x86-specific
500    ///
501    /// This type is the same as the `__m256h` type defined by Intel,
502    /// representing a 256-bit SIMD register which internally is consisted of
503    /// 16 packed `f16` instances. its purpose is for f16 related intrinsic
504    /// implementations.
505    ///
506    /// The in-memory representation of this type is the same as the one of an
507    /// equivalent array (i.e. the in-memory order of elements is the same, and
508    /// there is no padding); however, the alignment is different and equal to
509    /// the size of the type. Note that the ABI for function calls may *not* be
510    /// the same.
511    pub struct __m256h(16 x f16);
512
513    /// 512-bit wide set of 32 `f16` types, x86-specific
514    ///
515    /// This type is the same as the `__m512h` type defined by Intel,
516    /// representing a 512-bit SIMD register which internally is consisted of
517    /// 32 packed `f16` instances. its purpose is for f16 related intrinsic
518    /// implementations.
519    ///
520    /// The in-memory representation of this type is the same as the one of an
521    /// equivalent array (i.e. the in-memory order of elements is the same, and
522    /// there is no padding); however, the alignment is different and equal to
523    /// the size of the type. Note that the ABI for function calls may *not* be
524    /// the same.
525    pub struct __m512h(32 x f16);
526}
527
528/// The BFloat16 type used in AVX-512 intrinsics.
529#[repr(transparent)]
530#[derive(Copy, Clone, Debug)]
531#[allow(non_camel_case_types)]
532#[unstable(feature = "stdarch_x86_avx512_bf16", issue = "127356")]
533pub struct bf16(u16);
534
535impl bf16 {
536    /// Raw transmutation from `u16`
537    #[inline]
538    #[must_use]
539    #[unstable(feature = "stdarch_x86_avx512_bf16", issue = "127356")]
540    pub const fn from_bits(bits: u16) -> bf16 {
541        bf16(bits)
542    }
543
544    /// Raw transmutation to `u16`
545    #[inline]
546    #[must_use = "this returns the result of the operation, without modifying the original"]
547    #[unstable(feature = "stdarch_x86_avx512_bf16", issue = "127356")]
548    pub const fn to_bits(self) -> u16 {
549        self.0
550    }
551}
552
553/// The `__mmask64` type used in AVX-512 intrinsics, a 64-bit integer
554#[allow(non_camel_case_types)]
555#[stable(feature = "stdarch_x86_avx512", since = "1.89")]
556pub type __mmask64 = u64;
557
558/// The `__mmask32` type used in AVX-512 intrinsics, a 32-bit integer
559#[allow(non_camel_case_types)]
560#[stable(feature = "stdarch_x86_avx512", since = "1.89")]
561pub type __mmask32 = u32;
562
563/// The `__mmask16` type used in AVX-512 intrinsics, a 16-bit integer
564#[allow(non_camel_case_types)]
565#[stable(feature = "stdarch_x86_avx512", since = "1.89")]
566pub type __mmask16 = u16;
567
568/// The `__mmask8` type used in AVX-512 intrinsics, a 8-bit integer
569#[allow(non_camel_case_types)]
570#[stable(feature = "stdarch_x86_avx512", since = "1.89")]
571pub type __mmask8 = u8;
572
573/// The `_MM_CMPINT_ENUM` type used to specify comparison operations in AVX-512 intrinsics.
574#[allow(non_camel_case_types)]
575#[stable(feature = "stdarch_x86_avx512", since = "1.89")]
576pub type _MM_CMPINT_ENUM = i32;
577
578/// The `MM_MANTISSA_NORM_ENUM` type used to specify mantissa normalized operations in AVX-512 intrinsics.
579#[allow(non_camel_case_types)]
580#[stable(feature = "stdarch_x86_avx512", since = "1.89")]
581pub type _MM_MANTISSA_NORM_ENUM = i32;
582
583/// The `MM_MANTISSA_SIGN_ENUM` type used to specify mantissa signed operations in AVX-512 intrinsics.
584#[allow(non_camel_case_types)]
585#[stable(feature = "stdarch_x86_avx512", since = "1.89")]
586pub type _MM_MANTISSA_SIGN_ENUM = i32;
587
588/// The `MM_PERM_ENUM` type used to specify shuffle operations in AVX-512 intrinsics.
589#[allow(non_camel_case_types)]
590#[stable(feature = "stdarch_x86_avx512", since = "1.89")]
591pub type _MM_PERM_ENUM = i32;
592
593#[cfg(test)]
594mod test;
595#[cfg(test)]
596pub use self::test::*;
597
598macro_rules! as_transmute {
599    ($from:ty => $as_from:ident, $($as_to:ident -> $to:ident),* $(,)?) => {
600        impl $from {$(
601            #[inline]
602            pub(crate) const fn $as_to(self) -> crate::core_arch::simd::$to {
603                unsafe { transmute(self) }
604            }
605        )*}
606        $(
607            impl crate::core_arch::simd::$to {
608                #[inline]
609                pub(crate) const fn $as_from(self) -> $from {
610                    unsafe { transmute(self) }
611                }
612            }
613        )*
614    };
615}
616
617as_transmute!(__m128i =>
618    as_m128i,
619    as_u8x16 -> u8x16,
620    as_u16x8 -> u16x8,
621    as_u32x4 -> u32x4,
622    as_u64x2 -> u64x2,
623    as_i8x16 -> i8x16,
624    as_i16x8 -> i16x8,
625    as_i32x4 -> i32x4,
626    as_i64x2 -> i64x2,
627);
628as_transmute!(__m256i =>
629    as_m256i,
630    as_u8x32 -> u8x32,
631    as_u16x16 -> u16x16,
632    as_u32x8 -> u32x8,
633    as_u64x4 -> u64x4,
634    as_i8x32 -> i8x32,
635    as_i16x16 -> i16x16,
636    as_i32x8 -> i32x8,
637    as_i64x4 -> i64x4,
638);
639as_transmute!(__m512i =>
640    as_m512i,
641    as_u8x64 -> u8x64,
642    as_u16x32 -> u16x32,
643    as_u32x16 -> u32x16,
644    as_u64x8 -> u64x8,
645    as_i8x64 -> i8x64,
646    as_i16x32 -> i16x32,
647    as_i32x16 -> i32x16,
648    as_i64x8 -> i64x8,
649);
650
651as_transmute!(__m128 => as_m128, as_f32x4 -> f32x4);
652as_transmute!(__m128d => as_m128d, as_f64x2 -> f64x2);
653as_transmute!(__m256 => as_m256, as_f32x8 -> f32x8);
654as_transmute!(__m256d => as_m256d, as_f64x4 -> f64x4);
655as_transmute!(__m512 => as_m512, as_f32x16 -> f32x16);
656as_transmute!(__m512d => as_m512d, as_f64x8 -> f64x8);
657
658as_transmute!(__m128bh =>
659    as_m128bh,
660    as_u16x8 -> u16x8,
661    as_u32x4 -> u32x4,
662    as_i16x8 -> i16x8,
663    as_i32x4 -> i32x4,
664);
665as_transmute!(__m256bh =>
666    as_m256bh,
667    as_u16x16 -> u16x16,
668    as_u32x8 -> u32x8,
669    as_i16x16 -> i16x16,
670    as_i32x8 -> i32x8,
671);
672as_transmute!(__m512bh =>
673    as_m512bh,
674    as_u16x32 -> u16x32,
675    as_u32x16 -> u32x16,
676    as_i16x32 -> i16x32,
677    as_i32x16 -> i32x16,
678);
679
680as_transmute!(__m128h => as_m128h, as_f16x8 -> f16x8);
681as_transmute!(__m256h => as_m256h, as_f16x16 -> f16x16);
682as_transmute!(__m512h => as_m512h, as_f16x32 -> f16x32);
683
684mod eflags;
685#[stable(feature = "simd_x86", since = "1.27.0")]
686pub use self::eflags::*;
687
688mod fxsr;
689#[stable(feature = "simd_x86", since = "1.27.0")]
690pub use self::fxsr::*;
691
692mod bswap;
693#[stable(feature = "simd_x86", since = "1.27.0")]
694pub use self::bswap::*;
695
696mod rdtsc;
697#[stable(feature = "simd_x86", since = "1.27.0")]
698pub use self::rdtsc::*;
699
700mod cpuid;
701#[stable(feature = "simd_x86", since = "1.27.0")]
702pub use self::cpuid::*;
703mod xsave;
704#[stable(feature = "simd_x86", since = "1.27.0")]
705pub use self::xsave::*;
706
707mod sse;
708#[stable(feature = "simd_x86", since = "1.27.0")]
709pub use self::sse::*;
710mod sse2;
711#[stable(feature = "simd_x86", since = "1.27.0")]
712pub use self::sse2::*;
713mod sse3;
714#[stable(feature = "simd_x86", since = "1.27.0")]
715pub use self::sse3::*;
716mod ssse3;
717#[stable(feature = "simd_x86", since = "1.27.0")]
718pub use self::ssse3::*;
719mod sse41;
720#[stable(feature = "simd_x86", since = "1.27.0")]
721pub use self::sse41::*;
722mod sse42;
723#[stable(feature = "simd_x86", since = "1.27.0")]
724pub use self::sse42::*;
725mod avx;
726#[stable(feature = "simd_x86", since = "1.27.0")]
727pub use self::avx::*;
728mod avx2;
729#[stable(feature = "simd_x86", since = "1.27.0")]
730pub use self::avx2::*;
731mod fma;
732#[stable(feature = "simd_x86", since = "1.27.0")]
733pub use self::fma::*;
734
735mod abm;
736#[stable(feature = "simd_x86", since = "1.27.0")]
737pub use self::abm::*;
738mod bmi1;
739#[stable(feature = "simd_x86", since = "1.27.0")]
740pub use self::bmi1::*;
741
742mod bmi2;
743#[stable(feature = "simd_x86", since = "1.27.0")]
744pub use self::bmi2::*;
745
746mod sse4a;
747#[stable(feature = "simd_x86", since = "1.27.0")]
748pub use self::sse4a::*;
749
750mod tbm;
751#[stable(feature = "simd_x86", since = "1.27.0")]
752pub use self::tbm::*;
753
754mod pclmulqdq;
755#[stable(feature = "simd_x86", since = "1.27.0")]
756pub use self::pclmulqdq::*;
757
758mod aes;
759#[stable(feature = "simd_x86", since = "1.27.0")]
760pub use self::aes::*;
761
762mod rdrand;
763#[stable(feature = "simd_x86", since = "1.27.0")]
764pub use self::rdrand::*;
765
766mod sha;
767#[stable(feature = "simd_x86", since = "1.27.0")]
768pub use self::sha::*;
769
770mod adx;
771#[stable(feature = "simd_x86_adx", since = "1.33.0")]
772pub use self::adx::*;
773
774mod clflushopt;
775#[unstable(feature = "simd_x86_clflushopt", issue = "157096")]
776pub use self::clflushopt::*;
777
778#[cfg(test)]
779use stdarch_test::assert_instr;
780
781mod avx512f;
782#[stable(feature = "stdarch_x86_avx512", since = "1.89")]
783pub use self::avx512f::*;
784
785mod avx512bw;
786#[stable(feature = "stdarch_x86_avx512", since = "1.89")]
787pub use self::avx512bw::*;
788
789mod avx512cd;
790#[stable(feature = "stdarch_x86_avx512", since = "1.89")]
791pub use self::avx512cd::*;
792
793mod avx512dq;
794#[stable(feature = "stdarch_x86_avx512", since = "1.89")]
795pub use self::avx512dq::*;
796
797mod avx512ifma;
798#[stable(feature = "stdarch_x86_avx512", since = "1.89")]
799pub use self::avx512ifma::*;
800
801mod avx512vbmi;
802#[stable(feature = "stdarch_x86_avx512", since = "1.89")]
803pub use self::avx512vbmi::*;
804
805mod avx512vbmi2;
806#[stable(feature = "stdarch_x86_avx512", since = "1.89")]
807pub use self::avx512vbmi2::*;
808
809mod avx512vnni;
810#[stable(feature = "stdarch_x86_avx512", since = "1.89")]
811pub use self::avx512vnni::*;
812
813mod avx512bitalg;
814#[stable(feature = "stdarch_x86_avx512", since = "1.89")]
815pub use self::avx512bitalg::*;
816
817mod gfni;
818#[stable(feature = "stdarch_x86_avx512", since = "1.89")]
819pub use self::gfni::*;
820
821mod avx512vpopcntdq;
822#[stable(feature = "stdarch_x86_avx512", since = "1.89")]
823pub use self::avx512vpopcntdq::*;
824
825mod vaes;
826#[stable(feature = "stdarch_x86_avx512", since = "1.89")]
827pub use self::vaes::*;
828
829mod vpclmulqdq;
830#[stable(feature = "stdarch_x86_avx512", since = "1.89")]
831pub use self::vpclmulqdq::*;
832
833mod bt;
834#[stable(feature = "simd_x86_bittest", since = "1.55.0")]
835pub use self::bt::*;
836
837mod rtm;
838#[unstable(feature = "stdarch_x86_rtm", issue = "111138")]
839pub use self::rtm::*;
840
841mod f16c;
842#[stable(feature = "x86_f16c_intrinsics", since = "1.68.0")]
843pub use self::f16c::*;
844
845mod avx512bf16;
846#[stable(feature = "stdarch_x86_avx512", since = "1.89")]
847pub use self::avx512bf16::*;
848
849mod avxneconvert;
850#[stable(feature = "stdarch_x86_avx512", since = "1.89")]
851pub use self::avxneconvert::*;
852
853mod avx512fp16;
854#[stable(feature = "stdarch_x86_avx512fp16", since = "1.94.0")]
855pub use self::avx512fp16::*;
856
857mod kl;
858#[stable(feature = "keylocker_x86", since = "1.89.0")]
859pub use self::kl::*;
860
861mod movrs;
862#[unstable(feature = "movrs_target_feature", issue = "137976")]
863pub use self::movrs::*;
864
865mod avx512vp2intersect;
866#[unstable(feature = "stdarch_x86_avx512vp2intersect", issue = "111137")]
867pub use self::avx512vp2intersect::*;